﻿using System;
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace EVB.Collections.Immutable.Tests
{
    /// <summary>
    /// This is a test class for QueueTest and is intended
    /// to contain all QueueTest Unit Tests
    ///</summary>
    [TestClass]
    public sealed class QueueTest
    {
        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext { get; set; }

        #region Additional test attributes

        //
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //

        #endregion

        /// <summary>
        /// A test for ToArray
        ///</summary>
        [TestMethod]
        public void ToArrayTest()
        {
            var queue = Queue<int>.Empty;
            var expected = new int[] { 4, 2, 1, 7, 8, 9 };

            foreach (var item in expected)
                queue = queue.Enqueue(item);

            var actual = queue.ToArray();

            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void PeekTest()
        {
            const int expected = 17;
            var queue = Queue<int>.Empty.Enqueue(expected);

            Assert.AreEqual(expected, queue.Peek);
        }

        [TestMethod]
        public void DequeueTest()
        {
            var original = new int[] { 5, 2, 1, 7, 4, 5, 3 };
            var expected = (int[])original.Clone();
            var actual = new List<int>();

            var queue = Queue<int>.Empty;
            foreach (var item in original)
                queue = queue.Enqueue(item);

            for (; !queue.IsEmpty; queue = queue.Dequeue())
                actual.Add(queue.Peek);

            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        public void CountTest()
        {
            const int expected = 2;
            var stack = Queue<int>.Empty.Enqueue(0).Enqueue(0);

            Assert.AreEqual(expected, stack.Count);
        }

        [TestMethod]
        public void CopyToTest()
        {
            var expected = new int[] { 1, 4, 6, 3, 3 };
            var actual = new int[] { 1, 4, 0, 0, 3 };
            var queue = Queue<int>.Empty.Enqueue(6).Enqueue(3);

            ((System.Collections.ICollection)queue).CopyTo(actual, 2);

            CollectionAssert.AreEqual(expected, actual);
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void EmptyPeekTest()
        {
            var peek = Queue<int>.Empty.Peek;
        }

        [TestMethod]
        [ExpectedException(typeof(InvalidOperationException))]
        public void EmptyPopTest()
        {
            var stack = Queue<int>.Empty.Dequeue();
        }

        [TestMethod]
        public void EmptyCountTest()
        {
            Assert.AreEqual(0, Queue<int>.Empty.Count);
        }

        [TestMethod]
        public void EmptyToArrayTest()
        {
            var expected = new int[0];
            var actual = Queue<int>.Empty.ToArray();

            CollectionAssert.AreEqual(expected, actual);
        }
    }
}